#include "AIP.h"
#include <iostream>
AIP::AIP(void)
{
	m_Triggers = new LinkedList< Trigger >();
	m_TriggersIt = new Iterator< Trigger >( m_Triggers, 0 );
}

AIP::~AIP(void)
{

}

void AIP::Load( char* a_FilePath )
{
	m_Handler = new FileHandler();
	m_Handler->LoadFile( a_FilePath, "rb" );

	FILE* FileHandler = fopen( a_FilePath, "rb " );
	printf( "Begin of file reading: %i \n", FileHandler->_cnt);
	fread( &m_TriggerCount, sizeof( m_TriggerCount ), 1, FileHandler );
	fread( &m_IdleCheck, sizeof( m_IdleCheck ), 1, FileHandler );
	fread( &m_DamageCheck, sizeof( m_DamageCheck ), 1, FileHandler );

	//Reading LSTR
	fread( &m_TitleLength, sizeof( m_TitleLength ), 1, FileHandler );
	fread( &m_Title, m_TitleLength, 1, FileHandler );
	printf( "Done reading file info: %i\n", FileHandler->_cnt );
	for ( int i = 0; i < m_TriggerCount; i++ )
	{
		Trigger* newTrigger = new Trigger();
		newTrigger->Load( FileHandler );
		m_Triggers->AddEnd( newTrigger );
	}	
	printf( "Done reading triggers: %i\n", FileHandler->_cnt  );
	m_TriggersIt->First();

	fclose( FileHandler );
	
}

void AIP::Save( char* a_FilePath )
{
	FILE* FileHandler = fopen( a_FilePath, "wb" );
	printf( "Begin of file writing: %i \n", FileHandler->_cnt);
	fwrite( &m_TriggerCount, sizeof( m_TriggerCount ), 1, FileHandler );
	fwrite( &m_IdleCheck, sizeof( m_IdleCheck ), 1, FileHandler );	
	fwrite( &m_DamageCheck, sizeof( m_DamageCheck ), 1, FileHandler );

	//Writing LSTR
	fwrite( &m_TitleLength, sizeof( m_TitleLength ), 1, FileHandler );
	//int check = sizeof( m_TitleLength );
	fwrite( &m_Title, m_TitleLength, 1, FileHandler );
	printf( "Done of file writing: %i \n", 292 - ( 4096 - FileHandler->_cnt ) );
	do 
	{
		m_TriggersIt->CurrentNode()->m_Data->Save( FileHandler );
	} while ( m_TriggersIt->Loop() == true );	
	printf( "Done of triggers writing: %i \n", 292 -( 4096 - FileHandler->_cnt ) );
	fclose( FileHandler );
}

#pragma region Trigger
Trigger::Trigger()
{
	m_Blocks = new LinkedList< Block >();
	m_BlocksIt = new Iterator< Block >( m_Blocks, 0 );
}

Trigger::~Trigger()
{

}

void Trigger::Load( FILE* a_File )
{
	printf( "Begin reading trigger: %i\n", a_File->_cnt );
	fread( &m_TriggerName, sizeof( m_TriggerName ), 1 , a_File );
	fread( &m_BlockCount, sizeof( m_BlockCount ), 1, a_File );
	printf( "Done reading trigger info: %i\n", a_File->_cnt );
	for ( int i = 0; i < m_BlockCount; i++ )
	{
		Block* newBlock = new Block();
		newBlock->Load( a_File );
		m_Blocks->AddEnd( newBlock );
	}
	m_BlocksIt->First();
	printf( "Done reading trigger: %i\n", a_File->_cnt );
}

void Trigger::Save( FILE* a_File )
{
	printf( "Begin trigger writing: %i \n", 292 -( 4096 - a_File->_cnt ) );
	fwrite( &m_TriggerName, sizeof( m_TriggerName ), 1 , a_File );
	fwrite( &m_BlockCount, sizeof( m_BlockCount ), 1, a_File );
	printf( "Done trigger info writing: %i \n", 292 -( 4096 - a_File->_cnt ) );
	if ( m_BlockCount != 0 )
	{
		do 
		{
			m_BlocksIt->CurrentNode()->m_Data->Save( a_File );
		} while ( m_BlocksIt->Loop() == true );
	}
	printf( "Done trigger writing: %i \n", 292 -( 4096 - a_File->_cnt ) );
}

#pragma endregion Trigger

#pragma region Block
Block::Block()
{
	m_Conditions = new LinkedList< Condition >();
	m_ConditionsIt = new Iterator< Condition >( m_Conditions, 0 );
	m_Actions = new LinkedList< Action >();
	m_ActionsIt = new Iterator< Action >( m_Actions, 0 );
}

Block::~Block()
{

}

void Block::Load( FILE* a_File )
{
	printf( "Begin reading block: %i\n", a_File->_cnt );
	fread( &m_BlockName, sizeof( m_BlockName ), 1, a_File );
	fread( &m_ConditionCount, sizeof( m_ConditionCount ), 1, a_File );
	printf( "Done reading block info: %i\n", a_File->_cnt );
	for ( int i = 0; i < m_ConditionCount; i++ )
	{
		Condition* newCondition = new Condition();		
		newCondition->Load( a_File );
		m_Conditions->AddEnd( newCondition );
	}

	m_ConditionsIt->First();

	fread( &m_ActionCount, sizeof( m_ActionCount ), 1, a_File );

	for ( int i = 0; i < m_ActionCount; i++ )
	{
		Action* newAction = new Action();		
		newAction->Load( a_File );
		m_Actions->AddEnd( newAction );
	}

	printf( "Done reading block: %i\n", a_File->_cnt );

	m_ActionsIt->First();
}

void Block::Save( FILE* a_File )
{
	printf( "Begin of block writing: %i \n", 292 -( 4096 - a_File->_cnt ) );
	fwrite( &m_BlockName, sizeof( m_BlockName ), 1, a_File );
	fwrite( &m_ConditionCount, sizeof( m_ConditionCount ), 1, a_File );
	printf( "Done block info writing: %i \n", 292 -( 4096 - a_File->_cnt ) );

	if ( m_ConditionCount != 0)
	{
		do 
		{
			m_ConditionsIt->CurrentNode()->m_Data->Save( a_File );
		} while ( m_ConditionsIt->Loop() == true );
	}
	
	fwrite( &m_ActionCount, sizeof( m_ActionCount ), 1, a_File );

	if ( m_ActionCount != 0 )
	{
		do 
		{
			m_ActionsIt->CurrentNode()->m_Data->Save( a_File );
		} while ( m_ActionsIt->Loop() == true );
	}
	printf( "Done of block writing: %i \n", 292 -( 4096 - a_File->_cnt ) );
}

#pragma endregion Block

#pragma region Condition
Condition::Condition()
{

}

Condition::~Condition()
{

}

void Condition::Load( FILE* a_File )
{
	printf( "Begin readin condition: %i\n", a_File->_cnt );
	fread( &m_Size, sizeof( m_Size ), 1, a_File );
	fread( &m_Command, sizeof( m_Command ), 1, a_File );
	printf( "Done reading condition info: %i\n", a_File->_cnt );
	switch ( m_Command )
	{
	case CONDITION0:		
		m_Value = new Condition0();
		break;
	case CONDITION1:
		m_Value = new Condition1();
		break;
	case CONDITION2:

		m_Value = new Condition2();
		break;
	case CONDITION3:
		m_Value = new Condition3();
		break;
	case CONDITION4:
		m_Value = new Condition4();
		break;
	case CONDITION5:
		m_Value = new Condition5();
		break;
	case CONDITION6:
		m_Value = new Condition6();
		break;
	case CONDITION7:
		m_Value = new Condition7();
		break;
	case CONDITION8:
		m_Value = new Condition8();
		break;
	case CONDITION9: 
		m_Value = new Condition9();
		break;
	case CONDITION10:
		m_Value = new Condition10();
		break;
	case CONDITION11:
		m_Value = new Condition11();
		break;
	case CONDITION12:
		m_Value = new Condition12();
		break;
	case CONDITION13:
		m_Value = new Condition13();
		break;
	case CONDITION14:
		m_Value = new Condition14();
		break;
	case CONDITION15:
		m_Value = new Condition15();
		break;
	case CONDITION16:
		m_Value = new Condition16();
		break;
	case CONDITION17:
		m_Value = new Condition17();
		break;
	case CONDITION18:
		m_Value = new Condition18();
		break;
	case CONDITION19:
		m_Value = new Condition19();
		break;
	case CONDITION20:
		m_Value = new Condition20();
		break;
	case CONDITION21:
		m_Value = new Condition21();
		break;
	case CONDITION22:
		m_Value = new Condition22();
		break;
	case CONDITION23:
		m_Value = new Condition23();
		break;
	case CONDITION24:
		m_Value = new Condition24();
		break;
	case CONDITION25:
		m_Value = new Condition25();
		break;
	case CONDITION26:
		m_Value = new Condition26();
		break;
	case CONDITION27:
		m_Value = new Condition27();
		break;
	case CONDITION28:
		m_Value = new Condition28();
		break;
	case CONDITION29:
		m_Value = new Condition29();
		break;
	}

	m_Value->Load( a_File );
	printf( "Done reading condition: %i\n", a_File->_cnt );
	bool check = true;
}

void Condition::Save( FILE* a_File )
{
	printf( "Begin of condition writing: %i \n", 292 -( 4096 - a_File->_cnt ) );
	fwrite( &m_Size, sizeof( m_Size ), 1, a_File );
	fwrite( &m_Command, sizeof( m_Command ), 1, a_File );
	printf( "Done condition info writing: %i \n", 292 -( 4096 - a_File->_cnt ) );
	m_Value->Save( a_File );
	printf( "Done condition writing writing: %i \n", 292 -( 4096 - a_File->_cnt ) );
}

#pragma endregion Condition

#pragma region Action
Action::Action()
{
	
}

Action::~Action()
{

}

void Action::Load( FILE* a_File )
{
	fread( &m_Size, sizeof( m_Size ), 1, a_File );
	fread( &m_Command, sizeof( m_Command ), 1, a_File );
	
	switch ( m_Command )
	{
	case ACTION0:		
		m_Value = new Action0();
		break;
	case ACTION1:
		m_Value = new Action1();
		break;
	case ACTION2:
		if ( ( m_Size - 8 ) > 4 )
		{
			m_Value = new Action2();
		}		
		else
		{
			m_Value = new Action2Old();
		}
		break;
	case ACTION3:
		m_Value = new Action3();
		break;
	case ACTION4:
		m_Value = new Action4();
		break;
	case ACTION5:
		m_Value = new Action5();
		break;
	case ACTION6:
		m_Value = new Action6();
		break;
	case ACTION7:
		m_Value = new Action7();
		break;
	case ACTION8:
		m_Value = new Action8();
		break;
	case ACTION9: 
		m_Value = new Action9();
		break;
	case ACTION10:
		m_Value = new Action10();
		break;
	case ACTION11:
		m_Value = new Action11();
		break;
	case ACTION12:
		m_Value = new Action12();
		break;
	case ACTION13:
		m_Value = new Action13();
		break;
	case ACTION14:
		m_Value = new Action14();
		break;
	case ACTION15:
		m_Value = new Action15();
		break;
	case ACTION16:
		m_Value = new Action16();
		break;
	case ACTION17:
		m_Value = new Action17();
		break;
	case ACTION18:
		m_Value = new Action18();
		break;
	case ACTION19:
		m_Value = new Action19();
		break;
	case ACTION20:
		m_Value = new Action20();
		break;
	case ACTION21:
		m_Value = new Action21();
		break;
	case ACTION22:
		m_Value = new Action22();
		break;
	case ACTION23:
		m_Value = new Action23();
		break;
	case ACTION24:
		m_Value = new Action24();
		break;
	case ACTION25:
		m_Value = new Action25();
		break;
	case ACTION26:
		m_Value = new Action26();
		break;
	case ACTION27:
		m_Value = new Action27();
		break;
	case ACTION28:
		m_Value = new Action28();
		break;
	case ACTION29:
		m_Value = new Action29();
		break;
	case ACTION30:
		m_Value = new Action30();
		break;
	case ACTION31:
		m_Value = new Action31();
		break;
	case ACTION32:
		m_Value = new Action32();
		break;
	case ACTION33:
		m_Value = new Action33();
		break;
	case ACTION34:
		m_Value = new Action34();
		break;
	case ACTION35:
		m_Value = new Action35();
		break;
	case ACTION36:
		m_Value = new Action36();
		break;
	case ACTION37:
		m_Value = new Action37();
		break;
	}
	m_Value->Load( a_File );
}

void Action::Save( FILE* a_File )
{
	fwrite( &m_Size, sizeof( m_Size ), 1, a_File );
	fwrite( &m_Command, sizeof( m_Command ), 1, a_File );
	m_Value->Save( a_File );
}

#pragma endregion Action
